var Note = window.Note || {};
(function(){
	/**
	 *
	 *	Note Container Class
	 *
	 *	@namespace Note.Container
	 * 	@class Container
	 * 	@constructor
	 *	@param canvas {Object} canvas
	 *	@param bgImage {Object} 背景Image
	 * 	@param oConfig {Object} 用户配置参数
	 */
	Note.Container = function(canvas, bgImage, oConfig){
		this._initElements(canvas, oConfig.width, oConfig.height);
		this.setBackgroundImage(bgImage);
		this._initEvents();
	};
	
	/**
	 * Member Variable
	 */
	//Container组件
	Note.Container.prototype._topElement = null;
	Note.Container.prototype._containerElement = null;
	Note.Container.prototype._bgElement = null;
	Note.Container.prototype._topContext = null;
	Note.Container.prototype._containerContext = null;
	Note.Container.prototype._bgContext = null;
	//Canvas css类
	Note.Container.prototype._className = "Note";
	//背景网页
	Note.Container.prototype._backgroundImage = null;
	
	//绘图对象
	Note.Container.prototype._painter = new Note.Draw();
	//label集合
	Note.Container.prototype._labels = [];
	//操作类型:
	//绘制曲线, 直线, 矩形, 椭圆, 添加Label, 清空, 橡皮擦;
	//curve, line, rectangle, ellipse, label, clear, eraser
	Note.Container.prototype._opType = "curve";
	//橡皮擦的大小
	Note.Container.prototype._eraserSize = 30;
	//保存绘制图形的坐标(临时变量)
	Note.Container.prototype._drawCoords = [];
	Note.Container.prototype._isDraw = false;
	
	/**
	 *	函数名: _initElements
	 *	函数功能: 初始化容器组件
	 *	@param canvas {Object} top canvas对象
	 *	@param width {int} canvas宽度
	 *	@param height {int} canvas高度
	 */
	Note.Container.prototype._initElements = function(canvas, width, height){
		//初始化top canvas element
		this._topElement = canvas;
		this._topElement.width = width;
		this._topElement.height = height;
		this._topElement.style.zIndex = 2;
		this._topElement.className = this._className;
		
		//创建container canvas
		var containerEl = document.createElement("canvas");
		containerEl.id = this._topElement.id + "-container";
		containerEl.width = width;
		containerEl.height = height;
		containerEl.style.zIndex = 1;
		containerEl.className = this._className;
		this._containerElement = containerEl;
		
		//创建backgroung canvas
		var bgCanvasEl = document.createElement("canvas");
		bgCanvasEl.id = this._topElement.id + "-background";
		bgCanvasEl.width = width;
		bgCanvasEl.height = height;
		bgCanvasEl.style.zIndex = 0;
		bgCanvasEl.className = this._className;
		this._bgElement = bgCanvasEl;
		
		//将新建的canvas加入body中
		document.body.appendChild(containerEl);
		document.body.appendChild(bgCanvasEl);
		
		//取得绘图句柄
		this._topContext = this._topElement.getContext("2d");
		this._containerContext = this._containerElement.getContext("2d");
		this._bgContext = this._bgElement.getContext("2d");
	};
	
	/**
	 *	函数名: setBackgroundImage
	 *	函数功能: 设置背景图片
	 *	@param oImg {Object} 图片对象
	 */
	Note.Container.prototype.setBackgroundImage = function(oImg){
		this._backgroundImage = oImg;
		var width = this._topElement.width;
		var height = this._topElement.height;
		this._bgContext.clearRect(0, 0, width, height);
		this._bgContext.drawImage(oImg, 0, 0, oImg.width, oImg.height, 0, 0, width, height);
	};
	
	/**
	 *	函数名: _initEvents
	 *	函数功能: 初始化 容器事件
	 */
	Note.Container.prototype._initEvents = function(){
		EventOnHandler(this._topElement, "mousedown", this, "MouseDown");
		EventOnHandler(this._topElement, "mousemove", this, "MouseMove");
		EventOnHandler(this._topElement, "mouseup", this, "MouseUp");
	};
	
	/**
	 *	函数名: MouseDown
	 *	@param e {Object} 鼠标事件参数
	 */
	Note.Container.prototype.MouseDown = function(e){
		var pos = this.getMousePosition(e);
		if(this._opType != null && this._opType != "label"){
			this._drawCoords = [];
			this._drawCoords.push(pos);
			this._isDraw = true;
		}else if(this._opType == "label"){
			this.addLabel({
				id: this._labels.length+1, 
				left: pos.x,
				top: pos.y,
				display: true,
				isCallback: true,
				callbackObj: this
			});
		}
	};
	
	/**
	 *	函数名: MouseMove
	 *	@param e {Object} 鼠标事件参数
	 */
	Note.Container.prototype.MouseMove = function(e){
		var pos = this.getMousePosition(e);
		if(this._isDraw){
			this._drawCoords.push(pos);
			this.renderTop();
		}
	};
	
	/**
	 *	函数名: MouseUp
	 *	@param e {Object} 鼠标事件参数
	 */
	Note.Container.prototype.MouseUp = function(e){
		var pos = this.getMousePosition(e);
		if(this._isDraw){
			this._drawCoords.push(pos);
			if(this._opType != "eraser") this.render();
			else this.clearTop();
			this._isDraw = false;
		}
	};
	
	/**
	 *	函数名: addLabel
	 *	功能: 增加一个label
	 *	@param oConfig {Object} 新增的label config信息
	 */
	Note.Container.prototype.addLabel = function(oConfig){
		var labelObj = new Note.Label(document.body, oConfig);
		this._labels.push(labelObj);
	};
	
	/**
	 *	函数名: deleteLabel
	 *	功能: 删除一个label,并且重新对label排序
	 *	@param obj {Object} 要删除的元素对象
	 */
	Note.Container.prototype.deleteLabel = function(obj){
		this._labels.remove(obj);
		for(var i = 0; i < this._labels.length; i++){
			this._labels[i].setId(i+1);
		}
	};
	
	/**
	 *	函数名: clearTop
	 *	功能: 清空Top层
	 */
	Note.Container.prototype.clearTop = function(){
		var width = this._topElement.width;
		var height = this._topElement.height;
		this._topContext.clearRect(0, 0, width, height);
	};
	
	/**
	 *	函数名: clearContainer
	 *	功能: 清空container层
	 */
	Note.Container.prototype.clearContainer = function(){
		var width = this._topElement.width;
		var height = this._topElement.height;
		this._containerContext.clearRect(0, 0, width, height);
	};
	
	/**
	 *	函数名: render
	 *	功能: 渲染container层
	 */
	Note.Container.prototype.render = function(){
		this.clearTop();
		this._painter.drawShape(this._containerContext, this._opType, this._drawCoords);
	};
	
	/**
	 *	函数名: renderTop
	 *	功能: 渲染top层
	 */
	Note.Container.prototype.renderTop = function(){
		var width = this._topElement.width;
		var height = this._topElement.height;
		this._topContext.clearRect(0, 0, width, height);
		if(this._opType == "eraser"){
			var now = this._drawCoords[this._drawCoords.length-1];
			var offset = this._eraserSize/2;
			var start = {x: now.x - offset, y: now.y - offset};
			this._topContext.strokeRect(start.x, start.y, this._eraserSize, this._eraserSize);
			this._containerContext.clearRect(start.x, start.y, this._eraserSize, this._eraserSize);
		}
		else this._painter.drawShape(this._topContext, this._opType, this._drawCoords);
	};

	/**
	 *	函数名: toImage
	 *	功能: 将标注的网页转化为Image
	 *	@return {String} 返回图片的src
	 */
	Note.Container.prototype.toImage = function(){
		var src = this._containerElement.toDataURL("image/png");
		var img = new Image();
		img.src = src;
		var width = this._topElement.width;
		var height = this._topElement.height;
		this._bgContext.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height);
		var data = this._bgElement.toDataURL("image/png");
		return data;
	};
	
	/**
	 *	函数名: save
	 *	功能: 保存用户标注信息
	 *	@return {contents, labels} 
	 *			contents: 用户标注的网页后生成的图片src 
	 *			labels: 用户标注的label控件信息
	 */
	Note.Container.prototype.save = function(){
		var labelConfig = [];
		for(var i = 0; i < this._labels.length; i++){
			labelConfig.push(this._labels[i].save());
		}
		return {
			contents: this.toImage(),
			labels: labelConfig
		};
	};
	
	/**
	 *	函数名: load
	 *	功能: 载入用户已标注的网页
	 *	@param data {contents, labels}
	 *			contents: 用户标注的网页后生成的图片src 
	 *			labels: 用户标注的label控件信息
	 */
	Note.Container.prototype.load = function(data){
		this.setBackgroundImage(data.contents);
		for(var i = 0; i < data.labels.length; i++){
			this.addLabel(data.labels[i]);
		}
	};
	
	/**
	 *	函数名: getMousePosition
	 *	功能: 转化鼠标坐标
	 *	@param e {Object} 鼠标信息
	 *  @return {x, y} 转化之后的坐标
	 */
	Note.Container.prototype.getMousePosition = function(e){
		var bbox = this._topElement.getBoundingClientRect();
		var canvas = this._topElement;
		return{
			x: e.clientX - bbox.left,// * (canvas.width  / bbox.width),
			y: e.clientY - bbox.top  //* (canvas.height / bbox.height)
		};
	};
	
	Note.Container.prototype.setOpType = function(type){
		this._opType = type;
	};

	/**
	 *	函数名: indexOf, remove
	 *	功能: 为Array类增加一个 根据值 删除元素的方法
	 */
	Array.prototype.indexOf = function(val) {
        for (var i = 0; i < this.length; i++) {
            if (this[i] == val) return i;
        }
        return -1;
    };

    Array.prototype.remove = function(val) {
        var index = this.indexOf(val);
        if(index > -1){
            this.splice(index, 1);
        }
    };
})();